package com.windy.kafka.sender.annotation.config;


import com.windy.kafka.sender.annotation.annotation.MessageSender;
import org.aopalliance.aop.Advice;
import org.springframework.aop.Pointcut;
import org.springframework.aop.support.AbstractPointcutAdvisor;
import org.springframework.aop.support.ComposablePointcut;
import org.springframework.aop.support.annotation.AnnotationMatchingPointcut;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.util.Assert;

import java.lang.annotation.Annotation;

/**
 * Created by liyufeng on 2022/3/22
 */
public class MessageAnnotationAdvisor  extends AbstractPointcutAdvisor implements BeanFactoryAware {

    private Advice advice;

    private Pointcut pointcut;


    @Override
    public Pointcut getPointcut() {
        return this.pointcut;
    }

    @Override
    public Advice getAdvice() {
        return this.advice;
    }

    public MessageAnnotationAdvisor(Advice advice) {
        this.advice = advice;
        this.pointcut = buildPointcut(MessageSender.class);
    }

    public void setMessageAnnotationType(Class<? extends Annotation> asyncAnnotationType) {
        Assert.notNull(asyncAnnotationType, "'messageAnnotationType' must not be null");
        this.pointcut = buildPointcut(asyncAnnotationType);
    }


    /**
     * 暂时只支持方法上
     * @param messageAnnotationType
     * @return
     */
    protected Pointcut buildPointcut( Class<? extends Annotation> messageAnnotationType) {
        ComposablePointcut result = null;
        Pointcut mpc = new AnnotationMatchingPointcut(null, messageAnnotationType, true);
        result = new ComposablePointcut(mpc);

        return (result != null ? result : Pointcut.TRUE);
    }



    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        if (this.advice instanceof BeanFactoryAware) {
            ((BeanFactoryAware) this.advice).setBeanFactory(beanFactory);
        }
    }
}
